Ext.ns("Game.tiny.Tetris");


/**
 * 游戏类
 * 对外开发的方法：
 * start
 * stop
 * pause
 * addControl 下、左、右、旋转、开始 
 * @class Game.tiny.Tetris
 * @extends Ext.util.Observable
 */
Game.tiny.Tetris = Ext.extend(Ext.util.Observable,{

  /**
   * 构造函数 
   * @param {string} main 游戏主窗口
   * @param {string} simple 下一个图形窗口
   * @param {string} info 游戏信息窗口 级别 分数   
   * @param {object} config 配置信息
   */
  constructor: function(main,simple,info,config){
    var self = this;
    Game.tiny.Tetris.superclass.constructor.apply(self, arguments);   

    // 基础
    self._config = config; // 配置 
    self._delay = self._config.delay; // 初始刷新时间间隔
    self._levelDelay = self._config.levelDelay; // 每级减少刷新时间
    // 游戏主窗口
    self._gamePanel = document.getElementById(main);   
    
    // 预览窗口 
    self._simplePanel = document.getElementById(simple); 
     
    // 游戏信息窗口 
    self._infoPanel = document.getElementById(info); 

    // GC
    self._mainPaper = Raphael(self._gamePanel,self._config.width*self._config.box, self._config.height*self._config.box);
    self._simplePaper = Raphael(self._simplePanel, self._config.box*4, self._config.height*4);
 
    self._scoreLevel = self._config.scoreLevel; // 每100分一级别

    self._interval = undefined;  // 主循环

    self._initData();
    
  },

  _initData:function(){
    var self = this;
    self._simpleData = []; // 预览盒子数据 box二维数组
    self._data = []; // 游戏窗口 box二维数组 并 初始化窗口数据
    // 升级相关
    self._level = 0; // 级别
    self._score = 0; // 获取分数
    self._setInfo();
     
    // 计算相关   
    self._simple = self._genSimple(); // 当前图形
    self._nextSimple = self._genSimple(); // 下一个图形
    
    self._pause = false; // 暂停标识
    self._start = false; // 开始标识 全局仅一次

    self._countCol = 0; // 默认计数列
    self._countRow = 0; // 默认计数行
 
    // 数据
    // 游戏主窗口
    for(var i=0;i < self._config.height;i++){
      var row = [];
      for(var j=0;j < self._config.width;j++){
        var box = new Game.tiny.Tetris_Box(self,j,i,self._mainPaper);
        box.init();
        row.push(box);
      }
      self._data.push(row);
    }

    // 预览窗口 
    for(var i=0;i < 4;i++){
      var row = [];
      for(var j=0;j < 4;j++){
        var box = new Game.tiny.Tetris_Box(self,j,i,self._simplePaper);
        box.init();
        row.push(box);
      }
      self._simpleData.push(row);
    }
  },

  /**
   * 生成实例图形 
   */
  _genSimple: function(){
    var pos = Math.floor(Math.random()*7); 
    var simple = new Game.tiny.Tetris_Simple(data[pos]);
    return simple;
  },

  /**
   * 设置信息窗体 
   */
  _setInfo:function(){
    var self = this;
    self._infoPanel.innerHTML = String.format("分数：{0}，级别：{1}",self._score,self._level);
  },
  
  /**
   * 绘制预览样本 
   */ 
  _drawSimpleNext: function(){ 
    var self = this;
    var data = self._nextSimple.getData();
    for(var i=0;i < data.length;i++){
      var arr = data[i];
      for(var j=0;j < arr.length;j++){
        var val = arr[j];
        self._simpleData[i][j].setValue(val);
        self._simpleData[i][j].draw();
      }
    }
  },

  /**
   * 绘制主窗口 
   */
  _drawMainBoxs: function(){
    var self = this;
    for(var i=0;i < self._data.length;i++){
      var dataBuf = self._data[i];
      for(var j=0;j < dataBuf.length;j++){
        dataBuf[j].draw();
      }
    }
  },
 
  /**
   * 刷新但不修改目前显示 
   */
  _flush: function(){
    var self = this;
    for(var i=0;i < self._data.length;i++){
      var dataBuf = self._data[i];
      for(var j=0;j < dataBuf.length;j++){
        if(dataBuf[j].getFlush()==1){
          dataBuf[j].setValue(0);
        }
      }
    }
  },

  /**
   * 主要计算 
   */
  _mainCalculate: function(){ 
    var self = this; 
    
    var simple = self._simple; //　当前图形
    var row = self._countRow; // 图形左上角所在行
    var column = self._countCol; // 图形左上角所在列
    var width = self._config.width;  // 宽度
    var height = self._config.height; // 高度
    
    // 重置可刷新数据
    self._flush();
    
    var data = self._simple.getData();

    /*
     * 判断是否沉底 沉底则直接固定 
     * 判断原则 看下位是否存在或者存在是否为1 只要有一个格子是1 马上固定
     */ 
    var bottom = false; 
    
    for(var i=0;i < data.length;i++){
      var dataBuf = data[i];
      for(var j=0;j < dataBuf.length;j++){
        var xBuf = j+column;
        var yBuf = i+row;
        if(dataBuf[j] == 1){ 
          if(xBuf >= 0 && yBuf >= 0 && xBuf < width && yBuf < height){ 
            if(self._data[yBuf][xBuf].getValue() != 1){
              self._data[yBuf][xBuf].setValue(dataBuf[j]); 
            } 
          } 
          // 判断沉底 
          if( self._countRow < height-self._lenOfSimple() ){
            if(  self._data[yBuf+1][xBuf].getValue() == 1 ) { // 沉底
              bottom = true; 
            }
          }else{ // 沉底
            bottom = true;  
          } 
        }
      }
    }  
    
    /*
     * 绘制主窗口
     */
    self._drawMainBoxs();

    // 判断是否可以行消
    self._delRow();

    // if(self._countRow >= height-self._lenOfSimple()){
    if(bottom){
      if(self._countRow != 0){
        self._setSimpleFlush(row,column);
        self._simple = self._nextSimple;
        self._nextSimple = self._genSimple();
        self._drawSimpleNext();
        self._countRow = 0;
      }else{
        self.stop();
        alert("游戏结束"); 
      }  
    }else{ 
      self._countRow ++;
    }
  },

  _delRow:function(){
    var self = this;
    var width = self._config.width;  // 宽度
    var height = self._config.height; // 高度
    var data = self._data;

    for(var i=0;i < data.length;i++){
      var dataBuf = data[i];
      var bool = true;
      for(var j=0;j < dataBuf.length;j++){
        if(self._data[i][j].getValue() == 0){
          bool = false;
        }
      }
      // 此行可以消除
      // 将此行上边的数据全部转移到此行之前即可 
      var k = i-1;
      if(bool){ 
        while(k >= 0){
          self._data[k+1] = self._data[k];
          k--;
        }
        self._data[0] = []; 
        for(var w=0;w < self._config.width;w++){
          var box = new Game.tiny.Tetris_Box(self,w,0,self._mainPaper);
          box.init();
          self._data[0].push(box);
        }
      }
    }  
  },

  _setSimpleFlush:function(row,column){
    var self = this;
    var width = self._config.width;  // 宽度
    var height = self._config.height; // 高度
    var data = self._simple.getData();
    for(var i=0;i < data.length;i++){
      var dataBuf = data[i];
      for(var j=0;j < dataBuf.length;j++){
        var xBuf = j+column;
        var yBuf = i+row;
        if(dataBuf[j] == 1){
          if(xBuf >= 0 && yBuf >= 0 && xBuf < width && yBuf < height){ 
            self._data[yBuf][xBuf].setFlush(0); 
          }   
        }
      }
    }  
  },


  _lenOfSimple:function(){
    var self = this;
    var data = self._simple.getData();
    var count = 0;
    for(var i = 0 ; i < data.length ; i++ ){
      var row = data[i];
      for(var j = 0 ; j < row.length ; j++ ){
        if(row[j]==1){
          count ++;
          break;
        }
      }
    }
    return count;
  },
 
  /**
   * 开始游戏
   * @method start 
   */
  start: function(){
    var self = this;
    self._pause = false;
    if(!self._start){
      self._start = true;
      self._drawSimpleNext(); 
      self._interval = setInterval(function(){   
        if(!self._pause){
          self._mainCalculate();
        } 
      },(self._delay - self._levelDelay*self._level)*1000);
    }  
  },

  /**
   * 停止游戏
   * @method stop 
   */
  stop: function(){ 
    var self = this;
    self._initData();
    clearInterval(self._interval);
  },

  /**
   * 添加控制器
   * 旋转 下 左 右 暂停
   * @method addControl
   */
  addControl: function(){
    var self = this;
    document.addEventListener("keyup",function(e){
      if(e.keyCode == 87){ // 上
        self._simple.rotate();
      }else if(e.keyCode == 83){ // 下
        self._countRow++;
      }else if(e.keyCode == 65){ // 左
        self._countCol--;
      }else if(e.keyCode == 68){ // 右
        self._countCol++;
      }
    });
  },

  /**
   * 暂停游戏
   * @method pause 
   */
  pause: function(){
    var self = this;
    self._pause = true;
  }
});    
 
 